package ecs.net.systems;

import ecs.core.BaseSystem;
import ecs.net.ByteBuffer;
import ecs.net.EventType;
import ecs.net.Status;
import ecs.net.components.SendDataComponent;
import ecs.net.components.SocketComponent;
import ecs.net.components.StatusComponent;
import net.ConcurrentQueue;

import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.CompletableFuture;

public class SendDataSystem extends BaseSystem {

    public SendDataSystem()
    {
        super();
        interestingComponentTypes(new Class[]{SocketComponent.class, StatusComponent.class
                , SendDataComponent.class});
    }

    public void startSend()
    {
        entityComponents().forEach(components -> {
            StatusComponent status = (StatusComponent) components.get(1);
            if(status.status() == Status.Connected)
            {
                SocketComponent socket = (SocketComponent) components.get(0);
                SendDataComponent sendData = (SendDataComponent) components.get(2);
                send(socket, status, sendData);
            }
        });
    }

    private void send(SocketComponent socket ,StatusComponent status, SendDataComponent sendData)
    {
        CompletableFuture.runAsync(()->{
            OutputStream os = null;
            try {
                os = socket.socket().getOutputStream();
                ConcurrentQueue<ByteBuffer> data = sendData.data();
                while(data.size()>0)
                {
                    data.dequeue().read(os);
                }
            } catch (IOException e) {
                if(os != null) {
                    try {
                        os.close();
                    } catch (IOException ex) {
                    }
                }
                status.status(Status.Closed);
                broadcast(EventType.SocketStatusChanged, e);
            }
        });
    }

}
